home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / MiniExamples / AppKit / TextORama / TextORama.m < prev    next >
Text File  |  1995-06-12  |  4KB  |  196 lines

  1. /* TextORama.m
  2.  *
  3.  *   TextORama is a subclass of Object which acts as the
  4.  * application delegate.
  5.  * 
  6.  *
  7.  * You may freely copy, distribute, and reuse the code in this example.
  8.  * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  9.  * fitness for any particular use.
  10.  *
  11.  * Written by:  Sharon Zakhour 
  12.  * Created:  Oct/91
  13.  */
  14.  
  15. #import "TextORama.h"
  16. #import "TurboTextField.h"
  17. #import "TurboTFCell.h"
  18.  
  19. @implementation TextORama
  20.  
  21. - appDidInit:sender
  22. {
  23.     id font;
  24.     
  25.     font = [Font newFont: "Helvetica" size: 16.0];
  26.     
  27.     [dateField setAutoJump:YES forLength:8];
  28.     [dateField setCustomFilter: (NXTextFilterFunc)dateFilter];
  29.     [[dateField cell] setFont: font];
  30.  
  31.     [socSecField setAutoJump:YES forLength:11];
  32.     [socSecField setCustomFilter: (NXTextFilterFunc)socSecFilter];
  33.     [[socSecField cell] setFont: font];
  34.  
  35.     [phoneField setMaxLength:8];
  36.     [phoneField setCustomFilter: (NXTextFilterFunc)phoneFilter];
  37.     [[phoneField cell] setFont: font];
  38.     
  39.     [self loadEmacsScrollView];
  40.     
  41.     return self;
  42. }
  43.  
  44.  
  45. #define IS_DATE_DELIMITER(ch) ((ch) == '/')
  46. #define IS_PHONE_DELIMITER(ch) ((ch) == '-')
  47. #define IS_NUMBER(ch) ((ch) >= '0' && (ch) <= '9')
  48. #define IS_LETTER(ch) ((ch) >= 'a' && (ch) <= 'z' || (ch) >= 'A' && (ch) <= 'Z')
  49.  
  50. // This could easily be extended to include letters with diacritics.
  51. // See Chapter 6 Summary for KeyInfo for a full listing of keyboard
  52. // event information.
  53. #define IS_VALID_ASCII(ch)    ((ch) >= ' ' && (ch) <= '~')
  54.  
  55. char *dateFilter(id textObj, char *inputText, int *inputLength, int position)
  56. {
  57.     BOOL ok = NO;
  58.     char    *dateString;
  59.     int        dateLength, tmp;
  60.     
  61.     switch(position) 
  62.     {
  63.  
  64.     case 2: case 5:
  65.         ok = IS_DATE_DELIMITER(*inputText);
  66.         if (!ok && IS_VALID_ASCII(*inputText))  NXBeep();
  67.         break;
  68.  
  69.     default:
  70.         ok = IS_NUMBER(*inputText);
  71.         if (!ok && IS_VALID_ASCII(*inputText))  NXBeep();
  72.         break;
  73.     }
  74.     
  75.     // Let's do some actual date validation...
  76.     dateLength = [textObj textLength];
  77.     dateString = malloc(dateLength + 1);
  78.     [textObj getSubstring:dateString start:0 length:dateLength];
  79.     
  80.     if (!ok)
  81.     {
  82.     *inputLength = 0;
  83.     free(dateString);
  84.     return "";
  85.     }
  86.     
  87.     switch (dateLength)
  88.     {
  89.     case 1:
  90.     dateString[1] = '\0';
  91.     tmp = atoi(&dateString[0]);
  92.     ok = (tmp == 0 || tmp == 1);
  93.     break;
  94.     case 2:
  95.     dateString[2] = '\0';
  96.     tmp = atoi(&dateString[0]);
  97.     ok = (tmp >= 1 && tmp <= 12);
  98.     break;
  99.     case 4:
  100.     dateString[4] = '\0';
  101.     tmp = atoi(&dateString[3]);
  102.     ok = (tmp >= 0 && tmp <= 3);
  103.     break;
  104.     case 5:
  105.     dateString[5] = '\0';
  106.     tmp = atoi(&dateString[3]);
  107.     ok = (tmp >= 1 && tmp <= 31);
  108.     break;
  109.     case 7:
  110.     dateString[7] = '\0';
  111.     tmp = atoi(&dateString[6]);
  112.     ok = (tmp == 8 || tmp == 9);
  113.     break;
  114.     case 8:
  115.     dateString[8] = '\0';
  116.     tmp = atoi(&dateString[6]);
  117.     ok = (tmp >= 80 && tmp <= 99);
  118.     break;
  119.     }
  120.     
  121.     free(dateString);    
  122.     if (ok) return inputText;
  123.     *inputLength = 0;
  124.     return "";
  125. }
  126.  
  127. char *socSecFilter(id textObj, char *inputText, int *inputLength, int position)
  128. {
  129.     BOOL ok = NO;
  130.     
  131.     switch(position) 
  132.     {
  133.     case 3: case 6:
  134.         ok = IS_PHONE_DELIMITER(*inputText);
  135.         if (!ok && IS_VALID_ASCII(*inputText))  NXBeep();
  136.         break;
  137.  
  138.     default:
  139.         ok = IS_NUMBER(*inputText);
  140.         if (!ok && IS_VALID_ASCII(*inputText))  NXBeep();
  141.         break;
  142.     }
  143.     if (ok) return inputText;
  144.     *inputLength = 0;
  145.     return "";
  146. }
  147.  
  148. char *phoneFilter(id textObj, char *inputText, int *inputLength, int position)
  149. {
  150.     BOOL ok = NO;
  151.     
  152.     switch(position) 
  153.     {
  154.     case 3:
  155.         ok = IS_PHONE_DELIMITER(*inputText);
  156.         if (!ok && IS_VALID_ASCII(*inputText))  NXBeep();
  157.         break;
  158.  
  159.     default:
  160.         ok = IS_NUMBER(*inputText);
  161.         if (!ok && IS_VALID_ASCII(*inputText))  NXBeep();
  162.         break;
  163.     }
  164.     if (ok) return inputText;
  165.     *inputLength = 0;
  166.     return "";
  167. }
  168.  
  169. // Load the EMACS window with some text so that we can play with the emacs
  170. // bindings!!
  171. - loadEmacsScrollView
  172. {
  173.     id  theTO;
  174.     NXStream *s = (NXStream *)nil;
  175.     char buf[256];
  176.     const char *bp;
  177.     
  178.     theTO = [emacsScrollView docView];
  179.     
  180.     // Open a memory stream on the data file and read it into the text object.
  181.     bp = [[NXBundle mainBundle] directory];
  182.     sprintf(buf, "%s/SoapStory.rtf", bp);
  183.     s = NXMapFile(buf, NX_READONLY);
  184.     if (s)
  185.     {
  186.     [theTO readRichText:s];
  187.     NXCloseMemory(s, NX_FREEBUFFER);
  188.     }
  189.     
  190.     [[emacsScrollView window] orderFront:nil];
  191.     
  192.     return self;
  193. }
  194.  
  195. @end
  196.